package org.op.service.wwcache;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import org.op.service.WwDocumentInfo;
import org.op.service.config.ConfigKeys;
import org.op.service.config.ConfigurationService;

public class WikiwordCacheServiceImpl implements WikiwordCacheService {

	Properties aliases; // maps alias to file path
	
	private ConfigurationService configService;
	
	public WikiwordCacheServiceImpl() {

	}
	
	private String getAliasPath() throws Exception {
		
		String workspacePath = configService.getProperty(ConfigKeys.KEY_CURRENT_WORKSPACE);
		String aliasFilename = configService.getProperty(ConfigKeys.ALIAS_FILE);
		String aliasPath = workspacePath + System.getProperty("file.separator") + aliasFilename;
		
		return aliasPath;
	}
	
	public Properties loadAliases() throws Exception {

		String aliasPath = getAliasPath();
		
		aliases = new Properties();
		File file = new File(aliasPath);
		if (file.exists()) {
			InputStream is = new FileInputStream(file);
			aliases.load(is);
		} else {
			file.createNewFile();
		}
		
		return aliases;
	}
	

	public void saveAliases() throws Exception {
		
		String aliasPath = getAliasPath();
		OutputStream out = new FileOutputStream(aliasPath);
		
		aliases.store(out, "");
	}
	
	public Properties getAliasMap() {
		return aliases;
	}

	public WwDocumentInfo getInfoForWikiword(String ww) throws Exception {
		
		String path = aliases.getProperty(ww);
		WwDocumentInfo docInfo = new WwDocumentInfo(ww, path);
		return docInfo;
	}

	public void addAlias(String wikiword, String path) throws Exception {
		aliases.put(wikiword, path);
		saveAliases();
	}
	
	public void setAliasesForFile(List<String> aliasList, String filepath) throws Exception {
		
		// remove all references to the filepath
		Set<String> keys = aliases.stringPropertyNames();
		for (String key : keys) {
			String file = aliases.getProperty(key);
			if (file.equalsIgnoreCase(filepath)) {
				aliases.remove(key);
			}
		}
		
		// re-add from the new list of aliases
		for (String alias : aliasList) {
			aliases.setProperty(alias, filepath);
		}
		
		saveAliases();
	}
	

	public List<String> getAliasesForDocument(String filepath) {
		List<String> aliasList = new ArrayList<String>();
		Set<String> keys = aliases.stringPropertyNames();
		for (String key : keys) {
			String file = aliases.getProperty(key);
			if (file.equalsIgnoreCase(filepath)) {
				aliasList.add(key);
			}
		}
		return aliasList;
	}

	public void removeAlias(String wikiword) throws Exception {
		aliases.remove(wikiword);
		saveAliases();
	}

	public void updateAliasPath(String oldPath, String newPath) throws Exception {
		throw new Exception("Update AliasPath not implemented.");
	}

	public ConfigurationService getConfigService() {
		return configService;
	}

	public void setConfigService(ConfigurationService configService) {
		this.configService = configService;
	}


}
